package com.lcf.framework.config.enums;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.stereotype.Component;

/**
 * 枚举转换器工厂（无通配符泛型版本）
 * 负责将String类型的请求参数转换为具体的BaseEnum实现类
 * @author admin
 */
@Component
public class EnumConverterFactory implements ConverterFactory<String, BaseEnum<?>> {
    @Override
    public <T extends BaseEnum<?>> Converter<String, T> getConverter(Class<T> targetType) {
        return new StringToEnumConverter<>(targetType);
    }

    /**
     * 字符串转枚举的具体转换器
     */
    private record StringToEnumConverter<T extends BaseEnum<?>>(Class<T> enumType) implements Converter<String, T> {
        @Override
        public T convert(@NotNull String source) {
            if (StringUtils.isBlank(source)) {
                return null;
            }

            try {
                // 获取枚举的code类型
                Class<?> codeType = enumType.getMethod("getCode").getReturnType();

                // 根据code类型进行转换
                if (Integer.class.equals(codeType) || int.class.equals(codeType)) {
                    Integer code = Integer.parseInt(source.trim());
                    return convertByCode(code);
                } else if (String.class.equals(codeType)) {
                    return convertByCode(source.trim());
                } else if (Long.class.equals(codeType) || long.class.equals(codeType)) {
                    Long code = Long.parseLong(source.trim());
                    return convertByCode(code);
                } else if (Short.class.equals(codeType) || short.class.equals(codeType)) {
                    Short code = Short.parseShort(source.trim());
                    return convertByCode(code);
                } else if (Byte.class.equals(codeType) || byte.class.equals(codeType)) {
                    Byte code = Byte.parseByte(source.trim());
                    return convertByCode(code);
                } else {
                    throw new IllegalArgumentException("不支持的code类型: " + codeType.getName());
                }
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("枚举类 " + enumType.getName() + " 未实现getCode方法", e);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("参数 " + source + " 无法转换为数字类型", e);
            }
        }

        // 使用类型安全的转换方法
        private T convertByCode(Object code) {
            T[] enumConstants = enumType.getEnumConstants();
            if (enumConstants != null) {
                for (T enumConstant : enumConstants) {
                    if (enumConstant.getCode().equals(code)) {
                        return enumConstant;
                    }
                }
            }
            throw new IllegalArgumentException("无法找到code为 " + code + " 的 " + enumType.getSimpleName() + " 枚举值");
        }
    }
}
